#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "uart_tool.h"
#include "garbage.h"
#include "pwm.h"
#include "myoled.h"
#include "socket.h"

int serial_fd;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

// 检测进程是否在运行
static int detect_process(const char *process_name)
{
    int n = -1;
    FILE *fp;
    char buf[128] = {0};

    sprintf(buf, "ps -ax | grep %s | grep -v grep", process_name);

    //  3270 ?        Sl    16:54 ./mjpg_streamer -i ./input_uvc.so -d /dev/...
    fp = popen(buf, "r");
    if (fp == NULL)
    {
        printf("Failed to run command\n");
        exit(-1);
    }

    // 读取结果
    memset(buf, sizeof(buf), 0);
    if (fgets(buf, sizeof(buf), fp) != NULL)
    {
        // 获取进程ID
        n = atoi(buf);
    }

    // 关闭流并等待命令执行完成
    if (pclose(fp) == -1)
    {
        fprintf(stderr, "Error closing pipe\n");
        exit(-1);
    }

    return n;
}

void *pget_voice(void *arg)
{
    unsigned char *buffer = (unsigned char *)arg;

    if (-1 == serial_fd)
    {
        fprintf(stderr, "Error serial\n");
        exit(-1);
    }

    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    while (1)
    {
        serial_getString(serial_fd, buffer);
        printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
        if (buffer[2] == 0x46 && buffer[3] == 0x00)
        {
            pthread_mutex_lock(&mutex);
            // 数据清空
            buffer[2] = 0x00;
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);
        }
    }

    pthread_exit(NULL);
}

void *psend_voice(void *arg)
{
    // 该线程的资源在它终止时由系统来释放
    pthread_detach(pthread_self());

    unsigned char *buffer = (unsigned char *)arg;

    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    if (-1 == serial_fd)
    {
        fprintf(stderr, "Error serial\n");
        exit(-1);
    }

    printf("buffer[2] = %d\n", buffer[2]);
    if (buffer != NULL)
    {
        serial_sendString(serial_fd, buffer, 6);
    }

    pthread_exit(NULL);
}

void *ptrash_can(void *arg)
{
    pthread_detach(pthread_self());

    unsigned char *buffer = (unsigned char *)arg;

    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    if (buffer[2] == 0x41)
    {
        pwm_write(PWM_DRY);
        delay(2000);
        pwm_stop(PWM_DRY);
    }
    else if (buffer[2] == 0x43)
    {
        pwm_write(PWM_RECOVERABLE);
        delay(2000);
        pwm_stop(PWM_RECOVERABLE);
    }

    pthread_exit(NULL);
}

void *poled_show(void *arg)
{
    pthread_detach(pthread_self());

    myoled_init();
    myoled_show(arg);

    pthread_exit(NULL);
}

void *pcategory(void *arg)
{
    char *category = NULL;
    pthread_t send_voice_tid, trash_can_tid, oled_msg_tid;
    unsigned char *buffer = (unsigned char *)arg;

    while (1)
    {
        printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond, &mutex);
        pthread_mutex_unlock(&mutex);
        printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);

        // 调用拍照指令
        system(WGET_CMD);

        printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
        // 拍摄的图片存在
        if (0 == access(GARBAGE_FILE, F_OK))
        {
            printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
            // 开始识别垃圾类型
            category = garbage_category(category);
            printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
            printf("category = %s\n", category);

            if (strstr(category, "干垃圾"))
            {
                buffer[2] = 0x41;
            }
            else if (strstr(category, "湿垃圾"))
            {
                buffer[2] = 0x42;
            }
            else if (strstr(category, "可回收垃圾"))
            {
                buffer[2] = 0x43;
            }
            else if (strstr(category, "有害垃圾"))
            {
                buffer[2] = 0x44;
            }
            else
            {
                buffer[2] = 0x45;
            }

            //  语音回答垃圾线程
            pthread_create(&send_voice_tid, NULL, psend_voice, (void *)buffer);
            // 垃圾桶开盖线程
            pthread_create(&trash_can_tid, NULL, ptrash_can, (void *)buffer);
            // oled显示线程
            pthread_create(&oled_msg_tid, NULL, poled_show, (void *)buffer);
        }
        remove(GARBAGE_FILE);
    }
    pthread_exit(NULL);
}

void *psocket(void *arg)
{
    int s_fd, c_fd;
    int bytes_read;
    char buffer[16] = {0};
    struct sockaddr_in s_addr;
    struct sockaddr_in c_addr;

    s_fd = socket_init();
    if (-1 == s_fd)
    {
        fprintf(stderr, "error socket init\n");
        pthread_exit(NULL);
    }

    while (1)
    {
        printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
        // 4.accept
        int c_addrlen = sizeof(struct sockaddr_in);
        c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &c_addrlen);
        if (c_fd == -1)
        {
            perror("accept");
        }

        set_keepalive(c_fd, 10, 3, 3);

        printf("get connect--ip:%s,port:%d\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));

        while (1)
        {
            // 从套接字中读取数据
            memset(buffer, 0, sizeof(buffer));
            bytes_read = recv(c_fd, buffer, sizeof(buffer), 0);
            if (bytes_read < 0)
            {
                perror("recv failed");
                break;
            }
            else if (bytes_read == 0)
            {
                printf("Server closed the connection\n");
                break;
            }
            else
            {
                buffer[bytes_read] = '\0'; // 确保字符串以null结尾
                printf("Received: %s\n", buffer);

                if (strstr(buffer, "open"))
                {
                    pthread_mutex_lock(&mutex);
                    pthread_cond_signal(&cond);
                    pthread_mutex_unlock(&mutex);
                }
            }
        }

        close(c_fd);
    }

    close(s_fd);
    pthread_exit(NULL);
}

int main()
{
    int ret;
    unsigned char buffer[6] = {0xAA, 0X55, 0x00, 0x00, 0x55, 0xAA};
    pthread_t get_voice_tid, category_tid, socket_tid;

    // wiringPi库初始化
    wiringPiSetup();

    // python解释器初始化
    garbage_initialize();

    myoled_init();
    myoled_show_test();
    // 检测mjpg_streamer服务是否开启
    ret = detect_process("mjpg_streamer");
    if (-1 == ret)
    {
        fprintf(stderr, "mjpg_streamer not open\n");
        goto END;
    }

    // 打开串口
    serial_fd = myserialOpen(SERIAL_DEV, BAUD);
    if (-1 == serial_fd)
    {
        printf("open serial error!\n");
        goto END;
    }

    printf("%s|%s|%d\n", __FILE__, __func__, __LINE__);
    // 语音播报线程
    pthread_create(&get_voice_tid, NULL, pget_voice, (void *)buffer);
    // 阿里云识别交互线程
    pthread_create(&category_tid, NULL, pcategory, (void *)buffer);
    // 网络线程控制开始识别
    pthread_create(&socket_tid, NULL, psocket, (void *)buffer);

    pthread_join(get_voice_tid, NULL);
    pthread_join(category_tid, NULL);
    pthread_join(socket_tid, NULL);

    close(serial_fd);

END:
    garbage_Finalize();

    return 0;
}
